/*
 * mmap-manager.c
 *
 *  Created on: Sep 30, 2016
 *      Author: zhangzm
 */
#include <string.h>
#include <stdint.h>
#include "mmap-manager.h"
#include "log.h"

struct Map
{
	void* p;
	struct MMapPair fd;
};

#define MMAP_MAX (1024)
struct MMapManager
{
	int nb;
	struct Map map[MMAP_MAX];
};

static struct MMapManager g_mmap_manager;

void insert_mmap_pair(void* p, struct MMapPair *fd)
{
	int i = 0;
	for(i = 0; i < g_mmap_manager.nb; i++){
		if(g_mmap_manager.map[i].p > p){
			break;
		}
	}
	int mv_nb = g_mmap_manager.nb - i;
	int mv_start = i;
	memmove(&g_mmap_manager.map[mv_start+1], &g_mmap_manager.map[mv_start], mv_nb * sizeof(struct Map));
	memset(&g_mmap_manager.map[mv_start], 0, sizeof(struct Map));
	g_mmap_manager.map[mv_start].p = p;
	g_mmap_manager.map[mv_start].fd = *fd;
	g_mmap_manager.nb++;
}

void add_mmap(int fd, int offset, void* p, int pipe[2])
{
	if(g_mmap_manager.nb >= MMAP_MAX){
		return;
	}
	LOG_DEBUG("add mmp fd %d %p", fd, p);
	struct MMapPair insert;
	memset(&insert, 0, sizeof(insert));
	insert.fd = fd;
	insert.offset = offset;
	insert.pipe[0] = pipe[0];
	insert.pipe[1] = pipe[1];
	insert_mmap_pair(p, &insert);
}

int search_mmapi(void* p)
{
	int start = 0, end = g_mmap_manager.nb - 1;
	while(start <= end){
		int mid = (start + end) / 2;
		int64_t ret = (int64_t)p - (int64_t)g_mmap_manager.map[mid].p;
		if(0 == ret){
			return mid;
		}else if(ret < 0){
			end = mid - 1;
		}else{
			start = mid + 1;
		}
	}
	return -1;
}

void del_mmap(void* p)
{
	int index = search_mmapi(p);
	if(index < 0){
		LOG_ERROR("error del mmap %p", p);
		return;
	}
	int mv_start = index + 1;
	int mv_nb = g_mmap_manager.nb - 1 - index;
	memmove(&g_mmap_manager.map[index], &g_mmap_manager.map[mv_start], mv_nb * sizeof(struct Map));
	g_mmap_manager.nb--;
}

struct MMapPair search_mmap(void* p)
{
	int index = search_mmapi(p);
	if(index < 0){
		struct MMapPair mmp = MMapPair(-1, 0);
		return mmp;
	}
	// LOG_INFO("search %p ok %d", p, g_mmap_manager.map[index].fd);
	return g_mmap_manager.map[index].fd;
}
